
import { IResBundle } from "./IResBundle";
import { ResType } from "./ResDefine";
import { IBundleManager } from "./IBundleManager";
import { IEngine } from "../engine/IEngine";

/**
 * cgw0827 
 * AssetsBundle管理器
 */
export default class BundleManager implements IBundleManager {
    protected bundles: { [key: string]: IResBundle } = {}

    //默认的bundle
    protected _default: IResBundle = null;

    protected _factory: IEngine;
    constructor(factory: IEngine) {
        this._factory = factory;
        this._default = factory.getBundle(null, '')
    }

    getDefault() {
        return this._default;
    }

    private loadBundle(key: string, callback?: (err: string, bundle: IResBundle) => void) {
        if (key) {
            this.getDefault().loadRes(key, ResType.AssetBundle, (err: string, res: any) => {
                if (!err) {
                    this.addBundle(key, res)
                    if (callback) {
                        callback(null, this.getBundle(key));
                    }
                } else {
                    if (callback) {
                        callback(err, null);
                    }
                }
            })
        } else {
            callback(null, this.getDefault())
        }
    }

    addBundle(key: string, bundle: any): IResBundle {
        if (!key) {
            console.warn(' addBundle key is null', key)
            return;
        }

        let loader = this._factory.getBundle(bundle, key)
        this.bundles[key] = loader;
        return loader;
    }

    hasBundle(key: string): boolean {
        if (!key) {
            return true;
        }
        return this.bundles[key] != undefined;
    }

    getBundleAsync(key: string, callback: (err: string, bundle: IResBundle) => void, isAdd: boolean = false) {
        if (!key) {
            callback(null, this.getDefault())
        } else {

            let bundle: IResBundle = this.getBundle(key, isAdd)
            if (bundle) {
                callback(null, bundle)
            } else {
                this.loadBundle(key, (err: string, bundle: IResBundle) => {
                    if (!err) {
                        callback(null, this.getBundle(key, isAdd))
                    } else {
                        callback(err, null)
                    }
                })
            }
        }
    }

    getBundle(key: string, isAdd: boolean = false): IResBundle {
        if (!key) {
            return this.getDefault();
        }
        let bundle: IResBundle = this.bundles[key]
        if (!bundle) {
            let b = this.getDefault().getRes(key, ResType.AssetBundle)
            if (b) {
                bundle = this.addBundle(key, b)
            }
        }
        if (bundle && isAdd) {
            bundle.add()
        }
        return bundle;
    }


    removeBundle(key: string): void {
        if (!key) {
            return;
        }
        let bundle: IResBundle = this.bundles[key]
        if (bundle) {
            if (bundle.getCount() > 0) {
                bundle.sub();
                if (bundle.getCount() <= 0) {
                    bundle.clear()
                    delete this.bundles[key]
                }
            } else {
                bundle.clear()
                delete this.bundles[key]
            }

        }
    }

}